class PriorityQueue{
    constructor(){
        this.array = new Array(32);
        this.size=0
    }
     /**
     * 入队
     * @param key  入队元素
     */
    enQueue(key) {
        //队列长度超出范围，扩容
        if(this.size >= this.array.length){
            resize();
        }
        this.array[this.size++] = key;
        this.upAdjust();
    }
     /**
     * 出队
     */
    deQueue() {
        if(this.size <= 0){
            throw new Error("the queue is empty !");
        }
        //获取堆顶元素
        let head = this.array[0];
        //最后一个元素移动到堆顶
        
        this.array[0] = this.array[--this.size];
        this.array[this.size]=undefined;
        this.downAdjust();
        return head;
    }

     /**
     * 上浮调整
     */
    upAdjust() {
        let childIndex = this.size-1;
        let parentIndex;
        if(childIndex%2==0){// 右孩子节点
            parentIndex = (childIndex-2)/2;
        }else{
            parentIndex = (childIndex-1)/2;
        }
        // temp保存插入的叶子节点值，用于最后的赋值
        let temp = this.array[childIndex];
        while (childIndex > 0 && temp > this.array[parentIndex])
        {
            //无需真正交换，单向赋值即可
            this.array[childIndex] = this.array[parentIndex];
            childIndex = parentIndex;
            if(childIndex%2==0){// 右孩子节点
                parentIndex = (childIndex-2)/2;
            }else{
                parentIndex = (childIndex-1)/2;
            }
        }
        this.array[childIndex] = temp;
    }

    /**
     * 下沉调整
     */
    downAdjust() {
        // temp保存父节点值，用于最后的赋值
        let parentIndex = 0;
        let temp = this.array[parentIndex];
        let childIndex = 1;
        while (childIndex < this.size) {
            // 如果有右孩子，且右孩子大于左孩子的值，则定位到右孩子
            if (childIndex + 1 < this.size && this.array[childIndex + 1] > this.array[childIndex]) {
                childIndex++;
            }
            // 如果父节点大于任何一个孩子的值，直接跳出
            if (temp >= this.array[childIndex])
                break;
            //无需真正交换，单向赋值即可
            this.array[parentIndex] = this.array[childIndex];
            parentIndex = childIndex;
            childIndex = 2 * childIndex + 1;
        }
        this.array[parentIndex] = temp;
    }

    /**
     * 队列扩容
     */
    resize() {
        //队列容量翻倍
        let newArray = new Array(this.size);
        this.array = [...this.array, ...newArray];
    }
}

let priorityQueue = new PriorityQueue();
priorityQueue.enQueue(3);
priorityQueue.enQueue(5);
priorityQueue.enQueue(10);
priorityQueue.enQueue(2);
priorityQueue.enQueue(7);

console.log(priorityQueue);

console.log("出队元素：" + priorityQueue.deQueue());

console.log(priorityQueue);

console.log("出队元素：" + priorityQueue.deQueue());

console.log(priorityQueue);